/*
 * Copyright 2016-2017 lei.xu<xulei2008xulei@163.com>.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.san21go.jfinfunc.financ.irr;

import org.san21go.jfinfunc.AbstractFunction;
import org.san21go.jfinfunc.FinFuncRuntimeException;
import org.san21go.jfinfunc.FinFuncUtils;

public class IRR extends AbstractFunction<Double> {
	/** 迭代次数 */
	public static int LOOPNUM = 1000;
	/** 最小差异 */
	public static final double MINDIF = 0.00000001;

	private double[] values;
	private double guess;

	@Override
	public Double evaluate() throws FinFuncRuntimeException {

		double flowOut = values[0];
		double minValue = guess;
		double maxValue = 1d;
		double testValue = 0d;
		while (LOOPNUM > 0) {
			testValue = (minValue + maxValue) / 2;
			double npv = FinFuncUtils.NPV(values, testValue);
			if (Math.abs(flowOut + npv) < MINDIF) {
				break;
			} else if (Math.abs(flowOut) > npv) {
				maxValue = testValue;
			} else {
				minValue = testValue;
			}
			LOOPNUM--;
		}
		return testValue;
	}

	public IRR(double[] values, double guess) {
		super();
		this.values = values;
		this.guess = guess;
	}
}
